package noname1;

import java.io.IOException;
import java.util.Comparator;
import java.util.PriorityQueue;

import objects.UnrealObject;

import rok3.zesp.projekt.models.abstracts.AbstractActor;
import test.kryonet.network.DataType1;
import test.kryonet.network.HasTimeStamp;
import test.kryonet.network.Network;

import com.badlogic.gdx.utils.IntMap;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.kryonet.Server;

public class RealServer {
	PriorityQueue<HasTimeStamp> queue;
	IntMap<UnrealObject> actorMap;
	Server kryonetServer;
	UnrealWorld spdu;
	
	public RealServer () {
		queue = getQueue();
		actorMap = new IntMap<UnrealObject>(64);
		kryonetServer = getKryonetServer();
		
	}
	
	private Server getKryonetServer() {
		if ( kryonetServer == null ) {
			kryonetServer = new Server();
			Network.register(kryonetServer);
			kryonetServer.addListener(new Listener(){
				@Override
				public void received(Connection arg0, Object arg1) {
					synchronized (RealServer.this.queue ) {
						if ( arg1 instanceof HasTimeStamp ) {
							System.out.println(arg0.getRemoteAddressTCP() + " says :" + arg1 );
						}
					}
				}
			});
			try {
				kryonetServer.bind(Network.PORT_UDP);
			} catch (NumberFormatException | IOException e) {
				System.err.println("Error: server cant bind");
			}
		}
		return kryonetServer;
	}


	public void sendUpdateToClient() {
		
	}
	
	public boolean registerClient(UnrealObject actor) {
		if( actorMap.containsKey(actor.getId())) {
			return false;
		}
		actorMap.put(actor.getId(), actor);
		return true;
	}
	
	public void addToQueue(HasTimeStamp hts) {
		queue.add(hts);
	}
	
	public PriorityQueue<HasTimeStamp> getQueue () {
		if ( queue == null ) {
			queue = new PriorityQueue<HasTimeStamp>(16, new Comparator<HasTimeStamp>() {
				@Override
				public int compare(HasTimeStamp arg0, HasTimeStamp arg1) {
					if (arg0.getTimeStamp() < arg1.getTimeStamp()) return -1;
					else if (arg0.getTimeStamp() > arg1.getTimeStamp())return 1;
					return 0;
				}}
			);
		}
		return queue;
	}
	
	public void doUpdate() {
		
	}
	
	/*test */
	public static void main(String [] args ) {
		PriorityQueue<HasTimeStamp> queue = new PriorityQueue<HasTimeStamp>(16, new Comparator<HasTimeStamp>() {
			@Override
			public int compare(HasTimeStamp arg0, HasTimeStamp arg1) {
				if (arg0.getTimeStamp() < arg1.getTimeStamp()) return -1;
				else if (arg0.getTimeStamp() > arg1.getTimeStamp())return 1;
				return 0;
			}}
		);
	}

	public IntMap<UnrealObject> getActorMap() {
		return actorMap;
	}
}
